/**
 * 统一请求-ajax
 */
import type { RequestOptions, Result, UploadFileParams, UploadFileCallBack } from '/#/axios';
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError, } from 'axios'
import { HttpHeadEnum, ResultEnum, ContentTypeEnum } from '/@/common/enums/sysEnum';
import { getToken, getTenantId } from '/@/common/util/auth';
import { joinTimestamp, formatRequestDate } from '/@/common/util';
import { setObjToUrlParams, deepMerge } from '/@/utils';
import { isString } from '/@/common/util/is';
import { useUserStoreWithOut } from '/@/store/modules/user';
import { useI18n } from '/@/hooks/web/useI18n';
import { useGlobSetting } from '/@/hooks/setting';
import { useMessage } from '/@/hooks/web/useMessage';
const globSetting = useGlobSetting();
const { t } = useI18n();
const { createMessage, createErrorModal } = useMessage();

/**
 * HttpClient 是一个基于 Axios 的 HTTP 请求封装类
 */
export class HttpClient {
    private instance: AxiosInstance;
    private readonly options: RequestOptions;

    /**
     * 构造函数
     * @param config Axios 配置，如 baseURL、timeout 等
     */
    constructor(config: AxiosRequestConfig = {}, options: RequestOptions = {}) {
        // 创建 Axios 实例
        this.instance = axios.create(config);
        this.options = options;

        // 请求拦截器（可选）
        this.instance.interceptors.request.use((config) => {
            // 可在此处添加 token
            const token = getToken();
            if (token) {
                let tenantId: string | number = getTenantId();
                //   config.headers!.Authorization = `Bearer ${token}`
                config.headers!.Authorization = `${token}`;
                config.headers['X-Tenant-Id'] = tenantId ? tenantId : 0;
            }
            // console.log('axios请求头参数配置完成...', config)
            return config
        }, undefined);

        // 响应拦截器（可选）
        this.instance.interceptors.response.use((res: AxiosResponse<Result>) => {
            // console.log('[Axios 响应结果：]', res);
            return res;
        }, undefined);
    }

    // GET 请求
    get<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
        return this.request({ ...config, method: 'GET' }, options);
    }

    post<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
        
        return this.request({ ...config, method: 'POST' }, options);
    }

    put<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
        return this.request({ ...config, method: 'PUT' }, options);
    }

    delete<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
        return this.request({ ...config, method: 'DELETE' }, options);
    }

    /**
     * 通用请求方法
     * options：附带参数，todo:
     */
    async request<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
        this.beforeWrapperConfig(config, options);
        try {
            const opt: RequestOptions = Object.assign({}, this.options, options);
            const response = await this.instance.request(config);
            const res = this.afterWrapperResult(response, opt);
            return res as T
        } catch (error) {
            console.error('[HttpClient Request Error]', error)
            throw error // 抛出错误，让调用者处理
        }
    }

    /**
     * 前置封装config
     */
    private async beforeWrapperConfig(config, options: RequestOptions = {}) {
        const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options;
        const params = config.params || {};
        const data = config.data || false;
        if (config.method?.toUpperCase() === 'GET') {
            if (!isString(params)) {
                // 给 get 请求加上时间戳参数，避免从缓存中拿数据。
                config.params = Object.assign(params || {});
            } else {
                // 兼容restful风格
                config.url = config.url + params;
                config.params = undefined;
            }
        } else {
            if (!isString(params)) {
                formatDate && formatRequestDate(params);
                if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
                    config.data = data;
                    config.params = params;
                } else {
                    // 非GET请求如果没有提供data，则将params视为data
                    config.data = params;
                    config.params = undefined;
                }
                if (joinParamsToUrl) {
                    config.url = setObjToUrlParams(config.url as string, Object.assign({}, config.params, config.data));
                }
            } else {
                // 兼容restful风格
                config.url = config.url + params;
                config.params = undefined;
            }
        }
        return config;
    }

    /**
     * 后置封装result
     */
    private async afterWrapperResult(res, options: RequestOptions = {}) {
        const { isTransformResponse, isReturnNativeResponse } = options;
        // 是否返回原生响应头 比如：需要获取响应头时使用该属性
        if (isReturnNativeResponse) {
            return res;
        }
        // 不进行任何处理，直接返回
        // 用于页面代码可能需要直接获取code，data，message这些信息时开启
        if (!isTransformResponse) {
            return res.data;
        }
        const { data } = res;
        if (!data) {
            throw new Error(t('sys.api.apiRequestFailed'));
        }
        const { code, result, message, success } = data;
        // debugger
        const hasSuccess = data && Reflect.has(data, 'code') && (code === ResultEnum.SUCCESS || code === 200);
        if (hasSuccess) {
            if (success && message) {
                //信息成功提示
                createMessage.success(message);
            }
            return result;
        }
        let msg = '';
        // debugger
        switch (code) {
            case ResultEnum.TIMEOUT:
                msg = t('sys.api.timeoutMessage');
                const userStore = useUserStoreWithOut();
                userStore.setToken(undefined);
                userStore.logout(true);
                break;
            case ResultEnum.UNAUTHORIZED:
                msg = message;
                const userStore1 = useUserStoreWithOut();
                userStore1.setToken(undefined);
                userStore1.logout(true);
                break;
            default:
                if (message) {
                    msg = message;
                }
        }
        // errorMessageMode=‘modal’的时候会显示modal错误弹窗，而不是消息提示，用于一些比较重要的错误
        // errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
        if (options.errorMessageMode === 'modal') {
            createErrorModal({ title: t('sys.api.errorTip'), content: msg });
        } else if (options.errorMessageMode === 'message') {
            createMessage.error(msg);
        }
        throw new Error(msg || t('sys.api.apiRequestFailed'));
    }
}

// http请求工具
export const defHttp = new HttpClient(
    {
        baseURL: globSetting.apiUrl,
        timeout: 10 * 1000,                 // 默认 10 秒
        headers: { 'Content-Type': 'application/json;charset=UTF-8', },
    },
    {
        // 默认将prefix 添加到url
        joinPrefix: true,
        isReturnNativeResponse: false,  // 是否返回原生响应头 比如：需要获取响应头时使用该属性
        isTransformResponse: true,      // 需要对返回数据进行处理
        // post请求的时候添加参数到url
        joinParamsToUrl: false,
        // 格式化提交参数时间
        formatDate: true,
        // 异常消息提示类型
        errorMessageMode: 'message',
        // 成功消息提示类型
        successMessageMode: 'success',
        //  是否加入时间戳
        joinTime: true,
        // 忽略重复请求
        ignoreCancelToken: true,
        // 是否携带token
        withToken: true,
    },
);